<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow-IPC: Prerequisites and Setup</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow-IPC<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow-IPC project: Full implementation reference.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

</div><!-- top -->
<div><div class="header">
  <div class="headertitle"><div class="title">Prerequisites and Setup </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><center><b>MANUAL NAVIGATION:</b> <a class="el" href="api_overview.html">Preceding Page</a> - <a class="el" href="async_loop.html">Next Page</a> - <a href="./pages.html"><b>Table of Contents</b></a> - <a class="el" href="namespaceipc.html"><b>Reference</b></a></center><hr  />
<p >Here we discuss the environmental requirements for using Flow-IPC as well as quality-of-life setup basics including logging. (Or go back to preceding page: <a class="el" href="api_overview.html">API Overview / Synopses</a>.)</p>
<h2>OS and build environment </h2>
<dl class="section note"><dt>Note</dt><dd>In the short term (as of October 2023) this may become an open-source library with potentially wide distribution. Some of the below items may change in that case; for example it may become a header-only library or have that mode, and it may support additional OS rather than Linux. We would also include specific information on building it from source as befits a wide-release project. Until then we leave out specific instructions on building the library itself as outside the scope of the present document; while listing the environmental requirements/recommendations as follows. It is vaguely informational; until this is a wide-release library we stay away from rigorous build instructions here. Even once it becomes a wide-release product, possibly such instructions shall live outside this manual. Looking outside the src/ directory you'll certainly find the relevant build scripts which cover all that.</dd></dl>
<p>This is a Linux library (actually set of libraries, but in this Manual we treat Flow-IPC as a monolithic whole for simplicity). As of this writing it is to be built in 64-bit mode (x86-64 a/k/a AMD64). (Most code by far is not OS/architecture-specific, but at least certain aspects of the optionally-used SHM-jemalloc component are.) It is intended for use <em>at least</em> in a deployed server setting. As of this writing it relies on some Linux-specific techniques such as /proc/...pid.../ and /dev/shm/ semantics. In the future it is quite realistic it would be extended to other OS and architectures &ndash; possibly even Windows, but definitely macOS/Darwin/similar and orthogonally perhaps ARM64 and so on.</p>
<p >It is a linked library (libraries) that must be built in <b>C++17</b> compiler mode, as must any of its <code>#include</code>rs (translation units). It has been specifically tested (as of this writing) on a range of gcc and clang compilers/linkers. We omit details in this text, since this is likely to evolve over time. Generally such topics are well covered outside of src/ directories; start with the top-level <code>README.md</code> for an overview; it will point you to CMake scripts and so on &ndash; if there is interest.</p>
<p >Regarding the briefly-mentioned-above testing: As of this writing there is an automated CI/CD test suite which checks the various combinations of compiler and build-type (debug, release, various sanitizers, etc.) &ndash; both building and functionality. Again we omit details here; but as of this writing you can see the details at the official open-source project (GitHub organization "Flow-IPC," as I write this). You'll likely find a few files like <code>.github/...</code>, <code>conanfile.py</code>, and sanitizer-specific <code>.cfg</code> files which control this stuff. This is well outside our scope in this Manual, but we wanted you to be aware of such things.</p>
<p >Regarding test code itself: We do not talk about it in this Manual or Reference (again: out of scope); but it is in the same repo (repos). Some test code (of the unit-test variety) is in <code>test/</code> subdirs at various levels near production code; other test code is outside <code>src/</code> entirely &ndash; whether the unit test driver program(s) or the various integration-tests.</p>
<p >Flow-IPC strongly relies on a foundational library named Flow. We expose certain aspects of Flow, most notably for logging (discussed below), through the API as well. Informally and orthogonally, Flow is a nice tool we feel you're likely to find useful in any case at times. (For capnp users: an analogy might be capnp's use of their in-house <code>kj</code> library both internally and at times exposed in capnp's own API.) In any case you'll need to link and build with Flow to use Flow-IPC.</p>
<p >Flow has some dependencies, notably Boost, including certain linked (non-header-only) Boost libraries. So you'll need those.</p>
<p >capnp (Cap'n Proto) is an important dependency; you must build and link with capnp to use Flow-IPC. In particular that one, at the version we require, requires all <code>#include</code>rs to be built in C++17 mode. Flow-IPC inherits this requirement from capnp (as well as Flow) and is not shy about using C++17 including in .hpp files.</p>
<p >Lastly, if one chooses to use the SHM-jemalloc provider of zero-copy transmission and/or direct SHM use, then the jemalloc library is a dependency as well. Building jemalloc from source is a fairly simple task (a topic applicable if your consumer program does not already use jemalloc as a <code>malloc()</code> provider or other reasons).</p>
<p >All in all, if you've got a reasonably modern Linux build and runtime environment, and your application is built in at least C++17 mode, then there's nothing too exotic going on that would prevent the use of Flow-IPC (or Flow). Boost, capnp, and jemalloc do not introduce any array of exotic dependencies.</p>
<h2>Error reporting </h2>
<p >The standards and mechanics w/r/t error reporting are entirely inherited from Flow. Therefore, see the <code>namespace flow</code> doc header's "Error reporting" section. It applies verbatim (within reason) here. To summarize for your convenience, though: The error reporting is based on <a class="el" href="namespaceboost_1_1system.html" title="Small group of miscellaneous utilities to ease work with boost.system, joining its boost::system name...">boost.system</a> semantics which themselves are now adopted in standard C++ ("STL").</p><ul>
<li>If a function/method synchronously reports errors, it will take a (usually optional, defaulting to null) <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">ipc::Error_code</a> (a/k/a <code>boost::system::error_code</code>) <em>pointer</em> argument.<ul>
<li>If it is null: Any error is reported via thrown exception object; through this one can obtain the triggering <code>Error_code E</code>; and both <code>E</code> itself and <code>E.message()</code> are reasonable to print/log/analyze in that event. There is a wide range of Flow-IPC error codes indicating what went wrong; system (<code>errno</code>-based) and Boost codes may be generated too. Reference documentation announces which codes are possible for which APIs.</li>
<li>If it is not null: On success, the <code>Error_code</code> pointee is cleared (made falsy). On error it is filled with a truthy code <code>E</code>. See preceding paragraph regarding how to treat it.</li>
</ul>
</li>
<li>If any async API reports errors, then its handler function shall take a <code>const Error_code&amp;</code> argument. When the handler function is invoked, the <code>Error_code</code> shall be falsy on success, truthy on Error. In the latter case see preceding bullet point regarding how to treat it.</li>
</ul>
<p >Informally we recommend, when invoking a synchronous API:</p><ul>
<li>When prototyping just pass-in null <code>Error_code*</code>. It'll throw on error; you can catch it around the top level of your application, print the <code>Error_code</code> (from the exception object) and its <code>.message()</code>, and abort.</li>
<li>For production code it's your choice whether to use the exception-throwing or code-setting mode of a given API. For max performance <em>of the error path only</em> the safer choice is the code-setting mode. (If there is no error, then it does not matter. If errors are not expected in perf-critical paths of your application, then it also does not matter.)</li>
</ul>
<h2>Logging </h2>
<p >Flow-IPC goes to great lengths to log all relevant details while taking care not to affect performance while doing so, unless the log-level is raised to a specific level where detail takes precedence over performance impact. That said, as with other libraries like this (for example Boost, capnp) the primary &ndash; mandatory &ndash; way of supplying information about what has happened is through error reporting (see above). Logging is, therefore, optional. However we strongly suggest hooking up Flow-IPC's logging, so that you can reap the benefits of knowing what's going on.</p>
<p >Flow-IPC logs using <code>flow::log</code>, Flow's logging module. Do not be alarmed: this in <em>no</em> way dooms you to having to use some kind of heavy-weight rigid log-output system that you don't like. It is an API: it prepares the log message (spending processor cycles) <em>only</em> if the particular message's log-filter passes. Moreover if a message <em>is</em> deemed loggable, the actual method of output of the message &ndash; whether to stdout, a file, the network, whatever &ndash; is entirely your decision. Formally further information is available in <code>flow::log</code> documentation. For your convenience we <em>summarize</em> some basic information and typical options here. (Again &ndash; <code>flow::log</code> documentation gets into all the details. We're just trying to ease your mind here.) Here we go:</p>
<p >The simplest thing to do (though, again, we do not recommend it, as it's giving away a valuable source of visibility) is to disable logging from Flow-IPC entirely. To do so simply pass-in null whenever a particular <a class="el" href="namespaceipc.html" title="Catch-all namespace for the Flow-IPC project: A library/API in modern C++17 providing high-performanc...">ipc</a> API requires a <code>flow::log::Logger*</code> argument. ~No cycles will be spent on logging as a result.</p>
<p >The next simplest thing, and likely suitable at least for prototyping situations, is to output Flow-IPC logs to stdout and/or stderr. To do so construct a <code>flow::log::Simple_ostream_logger</code> (near the top of your application most likely), passing in the desired verbosity <code>enum</code> setting to its constructor's <code>Config</code> arg; plus <code>std::cout</code> and/or <code>std::cerr</code>. Then pass-in a pointer to this <code>Logger</code> throughout your application, when Flow-IPC requires a <code>Logger*</code> argument. Logs will go to stdout and/or stderr. (However beware that some log interleaving may occur if other parts of your application also log to the same stream concurrently &ndash; unless they, too, use the same <code>Simple_ostream_logger</code> object for this purpose.)</p>
<p >If your application is not based on <code>flow::log</code> (which of course is very much a possibility) then you will, longer-term, want to instead hook up your log system of choice to Flow-IPC. Don't worry: this is not hard. You need to implement the <code>flow::log::Logger</code> interface which consists of basically two parts:</p><ul>
<li><code>bool should_log()</code> which determines whethere a given message (based on its severity <code>enum</code> and, possibly, <code>Component</code> input) should in fact be output (for example your <code>should_log()</code> might translate the input <code>flow::log::Sev</code> to your own verbosity setting and output <code>true</code> or <code>false</code> accordingly).</li>
<li><code>void do_log()</code> which takes a pointer to the message string and metadata info (severity, file/line info among a few other things) and outputs some subset of this information as it sees fit. For example it might forward these to your own logging API &ndash; perhaps prefixing the message with some indication it's coming from Flow-IPC.</li>
</ul>
<p >Lastly, if your application <em>is</em> based on <code>flow::log</code> &ndash; or you would consider making it be that way &ndash; then we'd recommend the use of <code>flow::log::Async_file_logger</code>. This is a heavy-duty file logger: it performs log writing asynchronously in a separate thread and is rotation-friendly. (It even will, optionally, capture SIGHUP itself and reopen the file, so that your rotate daemon might rename the now-completed log file, moving it out of the way and archiving it or what-not.) <code>Async_file_logger</code> is meant for heavy-duty logging (and as of this writing may be gaining more features such as gzip-on-the-fly).</p>
<h2>Logging verbosity setting </h2>
<p >Regardless of which option you choose (null <code>Logger*</code> excepted, as then it is moot), it is important for proper visibility/performance balance to effect the correct log verbosity (a/k/a log-severity, log-level) setting for Flow-IPC. Per <code>flow::log</code> semantics:</p><ul>
<li>A log-level of <code>INFO</code> is recommended in production. Both error conditions and important non-error events shall be logged, but anything that would affect performance shall not.<ul>
<li>A log-level of <code>WARNING</code> would limit it to error conditions only. We don't recommend this in production, as it gives away too much interesting visibility and usually defeats the point of reasonably-performant logging.</li>
</ul>
</li>
<li>While debugging (and similar) the log-level <code>TRACE</code> is recommended. This may affect performance and produce large log files but will give great visibility into what's going on behind the scenes.<ul>
<li>You may pump it up to <code>DATA</code> which will add messages that include readouts of entire user messages. Files will get even larger, and performance will be possibly affected even more. However you may gain even nicer information on what exactly is flying around the IPC system.<ul>
<li>That said &ndash; in the specific case where you might want to log, specifically, a structured (capnp) message, you can do so yourself. <code>ostream&lt;&lt;</code> of <a class="el" href="classipc_1_1transport_1_1struc_1_1Msg__out.html" title="A structured out-message suitable to be sent via struc::Channel::send() (et al).">ipc::transport::struc::Msg_out</a> or <a class="el" href="classipc_1_1transport_1_1struc_1_1Msg__in.html">struc::Msg_in</a> and/or direct use of capnp's pretty-print API (see <a class="el" href="classipc_1_1transport_1_1struc_1_1Msg__out.html#a9894ad7ec2a46641c4b9b86664d0d465" title="The Body root capnp-generated mutator object.">ipc::transport::struc::Msg_out::body_root()</a> and <a class="el" href="classipc_1_1transport_1_1struc_1_1Msg__out.html#a9894ad7ec2a46641c4b9b86664d0d465" title="The Body root capnp-generated mutator object.">ipc::transport::struc::Msg_out::body_root()</a> docs for tips on that).</li>
</ul>
</li>
</ul>
</li>
</ul>
<p >With this setup stuff out of the way we're almost ready to start using Flow-IPC. Just one more bit of prerequisite knowledge necessary: <a class="el" href="async_loop.html">Asynchronicity and Integrating with Your Event Loop</a>.</p>
<hr  />
<center><b>MANUAL NAVIGATION:</b> <a class="el" href="api_overview.html">Preceding Page</a> - <a class="el" href="async_loop.html">Next Page</a> - <a href="./pages.html"><b>Table of Contents</b></a> - <a class="el" href="namespaceipc.html"><b>Reference</b></a></center> </div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 11 2025 20:02:26 for Flow-IPC by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
